package com.zou.mall.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.zou.common.config.ClientInfoHolder;
import com.zou.common.vo.UserVO;
import com.zou.mall.order.constant.OrderConstant;
import com.zou.mall.order.vo.SubmitOrderVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zou.common.utils.PageUtils;
import com.zou.common.utils.Query;

import com.zou.mall.order.dao.OrderDao;
import com.zou.mall.order.entity.OrderEntity;
import com.zou.mall.order.service.OrderService;

@Slf4j
@Service("orderService")
public class OrderServiceImpl extends ServiceImpl<OrderDao, OrderEntity> implements OrderService {


    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    ThreadPoolExecutor executor;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<OrderEntity> page = this.page(
                new Query<OrderEntity>().getPage(params),
                new QueryWrapper<OrderEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public void closeOrder(OrderEntity orderEntity) {
        log.info("订单包：{}", JSON.toJSONString(orderEntity));
        //1. 查看该订单的最新状态是已支付还是新创建
        //  tip: （OrderPayedListener.handlerAlipay回调监听的接口，接受支付宝的回调然后更新订单状态）
        //2. 若状态为新创建则为超时的未支付订单
        //3. 关闭此订单
            //3.1 更新库存轨迹日志表
            //3.2 释放预占库存
    }

    @Override
    public void submitOrder(SubmitOrderVO submitOrderVO) {

        UserVO clientInfo = ClientInfoHolder.getClientInfo();

        //token幂等性去重
        String script= "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        Long execute = redisTemplate.execute(new DefaultRedisScript<>(script,Long.class), Arrays.asList(OrderConstant.USER_ORDER_TOKEN_PREFIX + clientInfo.getPhone()), submitOrderVO.getOrderToken());
        if (0L == execute) {
            log.info("防重令牌验证失败");
        }else{
            //1. 创建订单和订单项
            //2. 算费
            //3. 保存订单
            //4. 锁定库存
            //5. 将订单报文发送到延迟队列进行消费
            OrderEntity orderEntity = submitOrderVO.getOrderEntity();
            rabbitTemplate.convertAndSend("order-event-exchange","order.create.order",orderEntity);
            //6. 清空购物车
        }




    }

    @Override
    public SubmitOrderVO confirmOrder() {
        SubmitOrderVO submitOrderVO = new SubmitOrderVO();
        UserVO clientInfo = ClientInfoHolder.getClientInfo();
        //幂等性的防重令牌
        String token = UUID.randomUUID().toString().replace("-", "");
        redisTemplate.opsForValue().set(OrderConstant.USER_ORDER_TOKEN_PREFIX +
                clientInfo.getPhone(), token, 30, TimeUnit.MINUTES);
        submitOrderVO.setOrderToken(token);
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setOrderSn(UUID.randomUUID().toString());
        orderEntity.setModifyTime(new Date());

        //通过rpc查询填充订单实体
        populateOrderEntity(orderEntity);

        submitOrderVO.setOrderEntity(orderEntity);
        return submitOrderVO;
    }

    private void populateOrderEntity(OrderEntity orderEntity) {

        //

    }


}